import { PWA_INSTALL } from '@/constants';
import setting from '@/settings/projectSetting';
import pinia from '@/store';
import { cloneDeep } from 'lodash-es';
import { initRequest, RequestCanceler } from '@vc/request';
import { useUserStoreWithOut } from '@/store/modules/user';
import { type ContextOptions } from '@vc/request/bridge';
import { cleanPiniaStorage, loadStyle } from '@vc/utils';
import { VcMessage, vLoading, createLoadingDirective } from 'vc';
import { initPwa } from 'vc/src/store/pwa/utils';
import type { LoadingBinding, VcLoading } from 'vc/src/web/loading/directive';
import type { App, Directive } from 'vue';
import Spin from '@/assets/loading.gif';
import pkgJson from '../package.json';

export async function initApplication(app: App<Element>) {
  loadStyle(setting.encryptIconLink);
  initPwa(pinia, PWA_INSTALL);
  initLoading(app);
  const useMock = import.meta.env.VITE_USE_MOCK === 'true';
  const api_prefix = import.meta.env.VITE_API_PREFIX;
  await _initRequest(useMock ? '/basic-api' : api_prefix);
}

function initLoading(app) {
  app.directive('loading', vLoading);
  
  const vSpin: Directive<VcLoading, LoadingBinding> = createLoadingDirective({
    text: '加载中...',
    img: Spin,
    rotate: false
  });
  
  app.directive('spin', vSpin);
}

async function _initRequest(apiUrl: ContextOptions['apiUrl']) {
  const userStore = useUserStoreWithOut();
  await initRequest({
    // 接口公共前缀
    apiUrl,
    getTokenFunction: () => {
      return userStore.getToken;
    },
    errorFunction: async (err) => {
      console.log(err, '请求出错了');
      const { code, msg } = err.response?.data || {};
      if (err.message !== 'canceled' && err?.code !== 'ERR_CANCELED') {
        VcMessage.error(msg || err.message);
      }
      
      if (err?.response?.status === 401) {
        userStore.resetGoLogin();
      }
    },
    unauthorizedFunction: async (msg) => {
      VcMessage.error(msg);
      const cancelRequest = new RequestCanceler();
      const pendMap = cloneDeep(cancelRequest.getAllPending());
      cancelRequest.removeAllPending();
      // await userStore.resetGoLogin();
      // pendMap.forEach(item => {
      //   item.config.url = item.config.url!.replace(import.meta.env.VITE_API_PREFIX, '');
      //   // @ts-ignore
      //   request[item.config.method!](item.config, item.config.requestOptions);
      // });
    },
    responseParams: {
      code: 'code',
      message: 'msg',
      data: 'data'
    }
  });
}
